package com.zmn.oms.business.impl.productcoderefund;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.productcoderefund.ProductCodeRefundBService;
import com.zmn.oms.common.constant.MessageQueueTagConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.dto.ProductCodeMsgDTO;
import com.zmn.oms.common.dto.QueueOrderNodeNotifyDTO;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.remark.OrderRemark;
import com.zmn.oms.model.entity.remark.OrderRemarkDetail;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkDetailService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 品码对接退款实现
 *
 * @author chengguang
 * @date 2022/08/22
 */
@Service
@Slf4j
public class ProductCodeRefundBServiceImpl implements ProductCodeRefundBService {

    @Resource
    private ZmnMQSender zmnMQSender;

    @Resource
    private OrderChangeRecordService orderChangeRecordService;

    @Resource
    private OrderExtendService orderExtendService;

    @Resource
    private OrderWorkService orderWorkService;

    @Resource
    private OrderDetailService orderDetailService;

    @Resource
    private OrderRemarkService orderRemarkService;

    @Resource
    private OrderRemarkDetailService orderRemarkDetailService;

    @Resource
    private OrderPayService orderPayService;

    /**
     * 品码渠道
     */
    private static final Integer PRODUCT_CODE_CHANNEL = 41355;


    @Override
    public void sendProductCodeRefundMsg(OrderWork orderWork, Integer logType) {
        // 1、获取渠道ID=41355、工单类型为：退款单，工单状态为：已完成的退款单记录，在退款完成后实时推送
        // 2、获取渠道ID=41355、工单类型为：新单，工单支付状态为：已退款or部分退款的记录，当工单取消后判断，满足条件则实时推送
        try {
            // 品码对接退款
            if (!Objects.equals(orderWork.getChannelId(), PRODUCT_CODE_CHANNEL)) {
                return;
            }

            log.info("ProductCodeRefundBServiceImpl.sendProductCodeRefundMsg 入参，orderWork:{},logType{}", orderWork, logType);

            Integer type = orderWork.getType();
            QueueOrderNodeNotifyDTO notifyDTO = null;
            Long orderId = orderWork.getOrderId();
            OrderDetail orderDetail = orderDetailService.findOrderDetailByKeySrcMaster(orderId);
            OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderIdSrcMaster(orderId);
            if (Objects.equals(type, OrderConsts.ORDER_TYPE_REFUND)) {
                if (!Objects.equals(orderWork.getPayStatus(), PayConsts.REFUND_STATUS_DONE)) {
                    return;
                }
                OrderWork dbOrderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, orderWork.getRefundWorkId());
                orderWork.setTotalAmount(dbOrderWork.getTotalAmount());
                orderWork.setOuterId(dbOrderWork.getOuterId());
//                log.info("退款单发消息，dbOrderWork：{}",JSON.toJSONString(dbOrderWork));
                notifyDTO = generateQueueOrderNodeNotifyDTO4NodeNotice2(dbOrderWork, orderDetail, orderExtend, null);
            } else {
                notifyDTO = generateQueueOrderNodeNotifyDTO4NodeNotice2(orderWork, orderDetail, orderExtend, null);
            }

            ProductCodeMsgDTO productCodeMsgDTO = formatProductCodeMsgDTO(orderWork);
            notifyDTO.setProductCodeMsgDTO(productCodeMsgDTO);
            zmnMQSender.send(MessageQueueTopicConstant.ZMN_TOPIC_OMS, MessageQueueTagConsts.PRODUCT_CODE_REFUND_TAG
                    , MessageQueueTagConsts.PRODUCT_CODE_REFUND_TAG + orderId, JSON.toJSONString(notifyDTO));

        } catch (Exception e) {
            e.printStackTrace();
            log.error("ProductCodeRefundBServiceImpl.sendProductCodeRefundMsg 失败：{}", e.getMessage(), e);
        }
    }

    @Override
    public ProductCodeMsgDTO formatProductCodeMsgDTO(OrderWork orderWork) {

        log.info("ProductCodeRefundBServiceImpl.formatProductCodeMsgDTO 开始。。");
        Long orderId = orderWork.getOrderId();
        Long workId = orderWork.getWorkId();

        ProductCodeMsgDTO productCodeMsgDTO = new ProductCodeMsgDTO();
        productCodeMsgDTO.setOuterId(orderWork.getOuterId());
        if (Objects.equals(orderWork.getType(),OrderConsts.ORDER_TYPE_REFUND)){
            productCodeMsgDTO.setWorkId(orderWork.getRefundWorkId());
        }else {
            productCodeMsgDTO.setWorkId(workId);
        }
        productCodeMsgDTO.setRefundAmount(orderWork.getRefundAmount());
        productCodeMsgDTO.setProductId(orderWork.getProductId());
        productCodeMsgDTO.setTotalAmount(orderWork.getTotalAmount());

        List<OrderPay> orderPays = orderPayService.listOrderPayByOrderIdAndWorkIdsAndTradeType(orderId,
                Collections.singletonList(workId), PayConsts.PAY_TRADE_TYPE_REFUND);
        if (CollectionUtil.isNotEmpty(orderPays)) {
            OrderPay orderPay = orderPays.get(0);
            productCodeMsgDTO.setRefundOutTradeNo(orderPay.getPayOutTradeNo());
            productCodeMsgDTO.setRefundType(orderPay.getRefundType());
        }
        // 退款原因
        OrderRemark orderRemark = orderRemarkService.findByOrderIdAndType(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_REFUND);
        if (Objects.nonNull(orderRemark)) {
            List<OrderRemarkDetail> orderRemarkDetails = orderRemarkDetailService.listOrderRemarkDetailByRemarkId(orderId, workId, orderRemark.getRemarkId());
            String content = StringUtils.isNotBlank(orderRemark.getContent()) ? orderRemark.getContent() : "";
            if (CollectionUtil.isNotEmpty(orderRemarkDetails)) {
                String mapName = orderRemarkDetails.get(0).getMapName();
                if (StringUtils.isNotBlank(mapName)) {
                    content = mapName + content;
                }
            }
            productCodeMsgDTO.setRefundRemark(content);
        }
        return productCodeMsgDTO;
    }


    private QueueOrderNodeNotifyDTO generateQueueOrderNodeNotifyDTO4NodeNotice2(OrderWork orderWork,
                                                                                OrderDetail orderDetail,
                                                                                OrderExtend dbOrderExtend,
                                                                                OmsOperator omsOperator) {
        QueueOrderNodeNotifyDTO build = QueueOrderNodeNotifyDTO.builder()
                .orderId(orderWork.getOrderId())
                .workId(orderWork.getWorkId())
                .receiveEntranceId(orderWork.getReceiveEntranceId())
                .type(orderWork.getType())
                .plat(orderWork.getPlat())
                .platWork(orderWork.getPlatWork())
                .status(orderWork.getStatus())
                .resultStatus(orderWork.getResultStatus())
                .channelId(orderWork.getChannelId())
                .phone(StringUtils.defaultString(orderDetail.getTelephone()))
                .updateBeforePhone("")
                .phone2(StringUtils.defaultString(orderDetail.getTelephone2()))
                .updateBeforePhone2("")
                .userId(orderWork.getUserId())
                .manageCompanyId(orderWork.getManageCompanyId())
                .companyId(orderWork.getCompanyId())
                .provinceId(orderDetail.getProvinceId())
                .cityId(orderWork.getCityId())
                .streetId(orderDetail.getStreetId())
                .streetSource(orderDetail.getStreetSource())
                .productGroupId(orderWork.getServProductGroupId())
                .productGroupName(orderWork.getServProductGroupName())
                .productInfo(orderDetail.getProductInfo())
                .masterId(orderWork.getMasterId())
                .masterName(orderWork.getMasterName())
                .servCategId(orderWork.getServCategId())
                .servCategName(orderDetail.getServCategName())
                .test(orderWork.getTest())
                .duplicate(orderWork.getDuplicate())
                .bizType(orderWork.getBizType())
                .servItemType(orderWork.getServItemType())
                .receiveTime(orderWork.getReceiveTime().getTime())
                .latitude(orderDetail.getLatitude())
                .longitude(orderDetail.getLongitude())
                .sendTime(DateUtil.getNow())
                .provinceName(orderDetail.getProvinceName())
                .cityName(orderDetail.getCityName())
                .countyName(orderDetail.getCountyName())
                .street(orderDetail.getStreet())
                .address(StringUtils.defaultString(orderDetail.getAddress(), ""))
                .build();
        // 完整地址
        build.setFullAddress(orderDetail.getProvinceName() + orderDetail.getCityName() +
                orderDetail.getCountyName() + orderDetail.getStreet() +
                StringUtils.defaultString(orderDetail.getAddress(), "")
        );

        // 预约时间
        if (Objects.nonNull(orderWork.getDutyTime())) {
            build.setDutyTime(orderWork.getDutyTime().getTime());
        }

        // clueId
        Optional.ofNullable(dbOrderExtend)
                .map(OrderExtend::getClueId)
                .ifPresent(build::setClueId);

        // 操作人
        if (Objects.nonNull(omsOperator)) {
            build.setOperatorId(omsOperator.getOperatorId());
            build.setOperatorType(omsOperator.getOperatorType());
            build.setOperator(omsOperator.getOperator());
        }

        // 下单呼叫ID
        if (Objects.nonNull(dbOrderExtend) && Objects.equals(build.getType(), OrderConsts.ORDER_TYPE_NEW)) {
            build.setReceiveCallId(dbOrderExtend.getCallId());
        }

        // 取责任工程师
        if (NumberUtil.isNotNullOrZero(orderWork.getMasterId())) {
            OrderChangeRecord orderChangeRecord = orderChangeRecordService.getChangeRecordByOrderId(orderWork.getOrderId());
            if (Objects.nonNull(orderChangeRecord)) {
                build.setCancelLiableMasterId(orderChangeRecord.getCancelLiableMasterId());
                build.setCancelLiableMasterName(orderChangeRecord.getCancelLiableMasterName());
            }
        }
        return build;
    }
}
